//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
namespace LargoCommon.Music
{
///
/// Harmonic Motive.
///
[Serializable]
public sealed class HarmonicMotive
{
#region Fields
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The given header.
/// The harmonic motive number.
public HarmonicMotive(MusicalHeader givenHeader, int harmonicMotiveNumber) : this() {
this.HarmonicStream = new HarmonicStream(givenHeader);
this.Shortcut = harmonicMotiveNumber.ToString();
this.Name = string.Format(CultureInfo.InvariantCulture, "H{0} from {1}", harmonicMotiveNumber, givenHeader.Name);
this.Number = harmonicMotiveNumber;
}
///
/// Initializes a new instance of the class.
///
public HarmonicMotive() {
this.RhythmicBehavior = new RhythmicBehavior();
this.HarmonicBehavior = new HarmonicBehavior();
}
#endregion
#region Properties
///
/// Gets or sets the full name.
///
///
/// The full name.
///
[UsedImplicitly]
public string Name { get; set; } //// CA1044 (FxCop)
///
/// Gets or sets the number.
///
/// Property description.
public int Number { get; set; }
///
/// Gets or sets Harmonic Motive Bars.
///
public HarmonicStream HarmonicStream { get; set; }
///
/// Gets the outline of bars.
///
/// Property description.
[UsedImplicitly]
public string OutlineOfBars {
get {
if (this.Length == 0) {
return string.Empty;
}
var outline = new StringBuilder();
foreach (var s in this.HarmonicStream.HarmonicBars) {
outline.Append(s.SimpleStructuralOutline);
outline.Append(" | ");
}
return outline.ToString();
}
}
///
/// Gets the length.
///
/// Property description.
public int Length {
get {
if (this.HarmonicStream?.HarmonicBars == null) {
return 0;
}
return this.HarmonicStream.HarmonicBars.Count;
}
}
///
/// Gets or sets the harmonic behavior.
///
///
/// The harmonic behavior.
///
public HarmonicBehavior HarmonicBehavior { get; set; }
///
/// Gets or sets the rhythmic behavior.
///
///
/// The rhythmic behavior.
///
public RhythmicBehavior RhythmicBehavior { get; set; }
///
/// Gets or sets the name.
///
///
/// Property description.
///
public string Shortcut { get; set; }
#endregion
#region Private Properties
/// Gets inner continuity.
/// Property description.
private float MeanContinuity {
get {
if (this.Length == 0) {
return 0;
}
var total = (from HarmonicBar s in this.HarmonicStream.HarmonicBars select s.HarmonicBehavior.Continuity).Sum();
var f = total / this.Length;
if (f != null) {
var meanContinuity = (float)f;
return meanContinuity;
}
return 0;
}
}
/// Gets inner impulse.
/// Property description.
private float MeanImpulse {
get {
if (this.Length == 0) {
return 0;
}
var total = (from HarmonicBar s in this.HarmonicStream.HarmonicBars select s.HarmonicBehavior.Impulse).Sum();
var f = total / this.Length;
if (f != null) {
var meanImpulse = (float)f;
return meanImpulse;
}
return 0;
}
}
/// Gets inner measure of dissonance.
/// Property description.
private float MeanConsonance {
get {
if (this.Length == 0) {
return 0;
}
var total = (from HarmonicBar s in this.HarmonicStream.HarmonicBars select s.HarmonicBehavior.Consonance).Sum();
var meanConsonance = total / this.Length;
return meanConsonance;
}
}
///
/// Gets the mean rhythmic mobility.
///
private float MeanRhythmicMobility {
get {
if (this.Length == 0) {
return 0;
}
var total = (from HarmonicBar s in this.HarmonicStream.HarmonicBars select s.RhythmicBehavior.Mobility).Sum();
var meanValue = total / this.Length;
return meanValue;
}
}
///
/// Gets the mean rhythmic tension.
///
private float MeanRhythmicTension {
get {
if (this.Length == 0) {
return 0;
}
var total = (from HarmonicBar s in this.HarmonicStream.HarmonicBars select s.RhythmicBehavior.Tension).Sum();
var meanValue = total / this.Length;
return meanValue;
}
}
#endregion
#region Public static methods
///
/// Gets the new harmonic motive.
///
/// The given header.
/// The harmonic motive number.
///
/// Returns value.
///
public static HarmonicMotive GetNewHarmonicMotive(MusicalHeader givenHeader, int harmonicMotiveNumber) {
//// var shortcut = ("0000" + harmonicMotiveNumber.ToString(CultureInfo.CurrentCulture)).Right(4);
var harMotive = new HarmonicMotive(givenHeader, harmonicMotiveNumber);
return harMotive;
}
///
/// Returns value of characteristic planned for given musical bar.
///
/// Number of musical bar.
/// The system.
///
/// Returns value.
///
/// No harmonic motive bar!
public HarmonicBar HarmonicBarWithNumber(int barNumber, MusicalSystem system) {
var listBars = this.HarmonicStream.HarmonicBars; //// (List)this.HarmonicBars;
var barCount = listBars.Count;
switch (barCount) {
case 1:
return listBars.First();
case 0:
throw new ArgumentException("No harmonic motive bar!");
}
int barnum; //// int lastBarNum = (from tmb in listBars select tmb.BarNumber).Max();
checked {
barnum = ((barNumber - 1) % barCount) + 1; //// % lastBarNum
}
var selectedBar = from trb in listBars where (trb.BarNumber == barnum) select trb;
//// var system = this.Core.Header.System;
var harmonicBar = selectedBar.FirstOrDefault() ??
HarmonicBar.EmptyBar(system.HarmonicOrder, system.RhythmicOrder);
return harmonicBar;
}
#endregion
#region Public methods
///
/// Adds the bar.
///
/// The harmonic motive bar.
public void AddBar(HarmonicBar bar) {
Contract.Requires(bar != null);
bar.Recompute();
((List)this.HarmonicStream.HarmonicBars).Add(bar);
}
///
/// Returns a that represents this instance.
///
///
/// A that represents this instance.
///
[UsedImplicitly]
public override string ToString() {
return this.Name;
}
///
/// Re-computes this instance.
///
public void Recompute() {
this.HarmonicBehavior.Continuity = this.MeanContinuity;
this.HarmonicBehavior.Impulse = this.MeanImpulse;
this.HarmonicBehavior.Consonance = this.MeanConsonance;
this.RhythmicBehavior.Mobility = this.MeanRhythmicMobility;
this.RhythmicBehavior.Tension = this.MeanRhythmicTension;
}
#endregion
}
}